gtkwindow: Ensure to revert focus to a parent on hide()
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 1 Oct 2020 14:54:10 +0000 (16:54 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Tue, 6 Oct 2020 01:29:13 +0000 (03:29 +0200)
When a widget is hidden, check harder for the keyboard focus being
contained in that widget, in order to reset it. Portions of the
focus child hierarchy may be outdated at the time, so it is more
reliable to check GtkRoot::focus (i.e. the property we intend to
update here).

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3214
gtk/gtkwindow.c

index 947b178f76d505cc254627c83aec530da4e44d10..6bdb06931b05f1f262b16507c388ee2b18603fc8 100644 (file)
@@ -5206,28 +5206,24 @@ _gtk_window_unset_focus_and_default (GtkWindow *window,
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   GtkWidget *child;
   GtkWidget *parent;
+  GtkWidget *focus;
 
   g_object_ref (window);
   g_object_ref (widget);
 
   parent = _gtk_widget_get_parent (widget);
-  if (gtk_widget_get_focus_child (parent) == widget)
+  focus = gtk_root_get_focus (GTK_ROOT (window));
+  if (focus && (focus == widget || gtk_widget_is_ancestor (focus, widget)))
     {
-      child = priv->focus_widget;
-      
-      while (child && child != widget)
-        child = _gtk_widget_get_parent (child);
-
-      if (child == widget)
+      while (parent)
         {
-          GtkWidget *new_focus;
-
-          if (GTK_IS_NATIVE (widget))
-            new_focus = gtk_widget_get_parent (widget);
-          else
-            new_focus = NULL;
+          if (_gtk_widget_get_visible (parent))
+            {
+              gtk_widget_grab_focus (parent);
+              break;
+            }
 
-         gtk_window_set_focus (GTK_WINDOW (window), new_focus);
+          parent = gtk_widget_get_parent (parent);
         }
     }